/*
    SlideScript - minimalistic top-down scripting language.
    (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2)

    View README file supplied with this software for more details
*/

#include "inc/deps.h"
#include "inc/math.h"
#include "inc/util.h"

EXPR sexpr [MAX_EXPR_ARGS];

static char expr_out[(MAX_EXPR_LEN*2)+1];

int get_expr_count()
{
    int yy;
    for(yy = 0; yy < MAX_EXPR_ARGS; yy++)
    {
        if(strlen(sexpr[yy].arg) > 0)
        {
            continue;
        }
        else
        {
            return yy;
        }
    }
    return 0;
}

void set_expr_arg(int index, char *arg)
{
    strcpy(sexpr[index].arg, arg);
}

// Main expr function
char *ss_expr(char *string)
{
    char *expr_tok, *f_end, *s_end, *calc_operator;
    int expr_argc, n;
    float first, second, finalf;

    expr_tok = strtok(string, " ");
    if(expr_tok == NULL)
        syn_error("ss:error:calc missing equation");

    // Clear arguments from previous calculations.
    for(int ff = 0; ff < MAX_EXPR_ARGS; ff++) bzero(sexpr[ff].arg, MAX_EXPR_LEN);

    // Set initial argument
    set_expr_arg(0, expr_tok);

    // Write new arguments
    n = 1;
    while((expr_tok = strtok(NULL, " ")) != NULL)
    {
        if(n > 3) syn_error("ss:error:calc recieved too many arguments");;
        int argc = get_expr_count();
        set_expr_arg(argc, expr_tok);
        n++;
    }

    // Check routine to make sure we're doing simple math xD
    expr_argc = get_expr_count();

    if(expr_argc > 3)
        syn_error("ss:error:calc only supports dual values (3 * 14)");

    first = strtof(sexpr[0].arg, &f_end);
    calc_operator = sexpr[1].arg;
    second = strtof(sexpr[2].arg, &s_end);

    switch (calc_operator[0]) {
        case '+':
            finalf = first + second;
            break;
        case '-':
            finalf = first - second;
            break;
        case '*':
            finalf = first * second;
            break;
        case '/':
            finalf = first / second;
            break;
            // operator doesn't match any case constant
        default:
            finalf = 0;
            syn_error("ss:error:calc operator not supported");
    }

    sprintf(expr_out, "%f", finalf);
    if(expr_out==NULL)
        syn_error("ss:error:calc illegal instruction");

    return expr_out;
}
